﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace OfficeClip.OpenSource.StyleFix.Drivers
{
    internal static class CodeUtils
    {

        public static CharacterPoint FindMatchingParenthesis(List<SFWorkingLine> lines, int lineIndex, int characterIndex)
        {
            int parenthesisCount = 1;
            // Skip the opening parenthesis, we've already counted it
            CharacterPoint position = new CharacterPoint(lineIndex, characterIndex + 1);
            while (parenthesisCount > 0 && position.LineNumber < lines.Count)
            {
                string line = lines[position.LineNumber].Line;
                while (parenthesisCount > 0 && position.Position < line.Length)
                {
                    if (line[position.Position] == '(')
                        parenthesisCount++;
                    else if (line[position.Position] == ')')
                        parenthesisCount--;
                    if (parenthesisCount == 0)
                    {
                        return position;
                    }
                    position.Position++;
                }
                position.Position = 0;
                position.LineNumber++;
            }
            return new CharacterPoint(-1, -1);
        }

        public static void CalculateNestingLevels(List<SFWorkingLine> workingLines)
        {
            bool isNested = false;
            int currentLevel = 0;
            int bracketLevel = 0;
            bool inString = false;
            bool inMuliString = false;
            bool inMuliComment = false;
           // bool classFound = false;
            Stack<int> classStack = new Stack<int>();

            foreach (SFWorkingLine workingLine in workingLines)
            {
                workingLine.NestingLevel = currentLevel;
                workingLine.NameSpaceRoot = classStack.Count == 0;
                if (!workingLine.NameSpaceRoot)
                    workingLine.ClassRoot = bracketLevel == classStack.Peek() + 1;
                bool skip = false;

                if (!isNested && Regex.IsMatch(workingLine.Line, @"(^|\s)class\s"))
                {
                    classStack.Push(bracketLevel);
                    currentLevel++;
                }


                for (int i = 0; i < workingLine.Line.Length; i++)
                {
                    switch (workingLine.Line[i])
                    {
                        case '\\':
                            if (inString && (i + 1 < workingLine.Line.Length && workingLine.Line[i + 1] == '\"'))
                            {
                                i++;
                            }
                            break;
                        case '@':
                            if (!(inMuliComment || inString || inMuliString))
                            {
                                if (i + 1 < workingLine.Line.Length && workingLine.Line[i + 1] == '\"')
                                {
                                    inMuliString = true;
                                    i++;
                                }
                            }
                            break;
                        case '/':
                            if (!(inMuliComment || inString || inMuliString))
                            {
                                if (i + 1 < workingLine.Line.Length && workingLine.Line[i + 1] == '*')
                                {
                                    inMuliComment = true;
                                    i++;
                                }
                                else if (i + 1 < workingLine.Line.Length && workingLine.Line[i + 1] == '/')
                                {
                                    skip = true;//no more to do on this line
                                }
                            }
                            break;
                        case '*':
                            if (inMuliComment && i + 1 < workingLine.Line.Length && workingLine.Line[i + 1] == '/')
                            {
                                inMuliComment = false;
                            }
                            break;
                        case '\"':
                            if (!(inMuliComment || inMuliString))
                            {
                                if (i > 0 && workingLine.Line[i - 1] == '\\')
                                {
                                    i++;
                                }
                                else
                                {
                                    inString = !inString;
                                }
                            }
                            else if (inMuliString)
                            {
                                if (i + 1 < workingLine.Line.Length && workingLine.Line[i + 1] == '\"')
                                {
                                    i++;
                                }
                                else
                                {
                                    inMuliString = false;
                                }
                            }
                            break;
                        case '{':
                            if (!(inString || inMuliString || inMuliComment))
                            {
                                //if (classFound)
                                //{
                                //    //nestLevel = bracketLevel;
                                //    classFound = false;
                                //}
                                bracketLevel++;
                            }
                            break;
                        case '}':
                            if (!(inString || inMuliString || inMuliComment))
                            {
                                bracketLevel--;
                                if (classStack.Count > 0)
                                {
                                    if (bracketLevel == classStack.Peek())
                                    {
                                        classStack.Pop();
                                        currentLevel--;
                                    }
                                }
                                else
                                {
                                    //End of class?
                                }
                            }
                            break;
                    }
                    if (skip)
                        break;
                }
            }

        }
    }
}
